package week08.jvm.engine;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

import week08.jvm.attr.CodeAttr;
import week08.jvm.clz.ClassFile;
import week08.jvm.cmd.ByteCodeCommand;
import week08.jvm.constant.MethodRefInfo;
import week08.jvm.method.Method;

public class ExecutorEngine {

	private Stack<StackFrame> stack = new Stack<StackFrame>();

	public ExecutorEngine() {

	}

	public void execute(Method mainMethod) {

		StackFrame mainFrame = StackFrame.create(mainMethod);
		stack.push(mainFrame);

		while (!stack.empty()) {

			StackFrame frame = stack.peek();

			ExecutionResult result = frame.execute();

			if (result.isPauseAndRunNewFrame()) {

				Method nextMethod = result.getNextMethod();
				StackFrame nextFrame = StackFrame.create(nextMethod);
				nextFrame.setCallerFrame(frame);
				setupFunctionCallParams(frame, nextFrame);

				stack.push(nextFrame);

			} else {

				stack.pop();

			}
		}

	}

	private void setupFunctionCallParams(StackFrame currentFrame, StackFrame nextFrame) {

		Method nextMethod = nextFrame.getMethod();
		
		
		List<String> paramList = nextMethod.getParameterList();
		
		//加上1 是因为要把this也传递过去
		
		int paramNum = paramList.size() + 1;
		
		
		List<JavaObject> values = new ArrayList<JavaObject>();
		
		//数据结构知识：  从栈中取出栈顶的x个元素
		while(paramNum>0){			
			values.add(currentFrame.getOprandStack().pop());
			paramNum --;
		}
		//数据结构知识：  把一个列表倒序排列
		List<JavaObject> params = new ArrayList<JavaObject>();
		
		for(int i=values.size()-1; i>=0 ;i--){
			params.add(values.get(i));
		}
		
		
		nextFrame.setLocalVariableTable(params);
		
	}
	

}
